package org.openfans.domain;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * Description：<br>
 * Date：2006-5-23<br>
 * 
 * @author pesome<br>
 * @email:pesome@gmail.com<br>
 */
public class Fans extends PersistentObject {
	private static final int EDIT_ARTICLE_SCORE = 2;

	private static final int EDIT_ROOTTAG_SCORE = 5;

	private static final int JUDGE_ROOTTAG_SCORE = 5;

	private static final int NEW_ARTICLE_SCORE = 5;

	private static final int NEW_ROOTTAG_SCORE = 10;

	public static final int ORDER_BY_HOT_DESC = 0;

	public static final int ORDER_BY_JOIN_DATE_DESC = 1;

	public static final int ORDER_BY_NAME_ASC = 2;

	private static final int SAVE_ARTICLE_SCORE = 3;

	// 用户固定自己的名字
	public static final int STATUS_PERMENENT = 2;

	private static final int DIGG_SCORE = 3;

	public static String getOrder(int type) {
		switch (type) {
		case ORDER_BY_NAME_ASC:
			return "nickName asc";
		case ORDER_BY_HOT_DESC:
			return "hot desc";
		case ORDER_BY_JOIN_DATE_DESC:
			return "joinDate desc";

		default:
			return "hot desc";
		}
	}

	private Set<Article> articleSet;

	private String blog;

	private String city;

	private String descn;

	private String email;

	private int emailOpenType;

	private int fansId;

	private Set<Feed> feeds;

	private Set<Group> groups;

	private int hot;

	private String icon;

	private Date joinDate;

	private String name;

	private String nickName;

	private Set<RootTag> rootTagSet;

	private Set<RootTagDigg> rootTagDiggSet;

	private int status;

	/**
	 * 订阅的feed列表
	 */
	private Set<FansSubFeed> subFeedSet;

	private Set<FansUsedTag> usedTagSet;

	private Set<UseStatus> useStatusSet;

	/**
	 * 功能说明：在网站发表文章，写作人和推荐人都是自己<br>
	 * 
	 * @param article
	 * @param tag
	 */
	void addArticle(Article article, Tag tag) {
		Date date = new Date();
		article.setSubmitDate(date);
		article.setPublishDate(date);
		article.setFans(this);
		article.setRecomFans(this);
		article.setPersistence(this.getPersistence());
		article.save();
		article.addTag(tag);
		tag.addArticle(article);
		this.addFansTag(tag);
		this.addHot(NEW_ARTICLE_SCORE);
	}

	/**
	 * 给用户增加tag，如果加过权重加1，否则新增用户tag<br>
	 * 
	 * @param tag
	 */
	void addFansTag(Tag tag) {
		for (FansUsedTag fut : this.getUsedTagSet()) {
			if (fut.getTag().getTagId() == tag.getTagId()) {
				fut.addFreq(1);
				return;
			}
		}

		// fans 第一次使用这个tag
		addNewUsedTag(tag);
	}

	void addFeed(Feed feed) {
		if (feeds == null) {
			feeds = new HashSet<Feed>();
		}
		feeds.add(feed);
	}

	void addGroup(Group group) {
		if (groups == null) {
			groups = new HashSet<Group>();
		}
		group.increaseFansCount(1);
		group.addFans(this);
		groups.add(group);

	}

	/**
	 * 增加用户的贡献度
	 * 
	 * @param i
	 */
	public void addHot(int i) {
		hot += i;
	}

	/**
	 * 
	 * @param tagTitle
	 * @return
	 */
	Tag addNewTagByTitle(String tagTitle) {
		Tag tag = new Tag();
		tag.setTitle(tagTitle);
		tag.setSubmitDate(new Date());
		tag.setFans(this);
		tag.setPersistence(this.getPersistence());
		tag.save();
		this.addNewUsedTag(tag);
		return tag;
	}

	/**
	 * 功能说明：给用户新增加tag<br>
	 * 创建者：张俊<br>
	 * 创建时间：2006-5-23<br>
	 * 
	 * @param tag
	 */
	private void addNewUsedTag(Tag tag) {
		FansUsedTag fut = new FansUsedTag(this, tag, 1);
		fut.setPersistence(this.getPersistence());
		fut.save();
		this.addUsedTag(fut);
	}

	void addRootTag(RootTag tag) {
		tag.setFans(this);
		tag.setPersistence(this.getPersistence());
		tag.save();
		// 新增软件,是第一次出现这个tag，肯定也是fans第一次使用这个tag
		addNewUsedTag(tag);
		this.addHot(NEW_ROOTTAG_SCORE);
	}

	void addUsedTag(FansUsedTag fansUsedTag) {
		if (usedTagSet == null) {
			usedTagSet = new HashSet<FansUsedTag>();
		}
		usedTagSet.add(fansUsedTag);
	}

	void addUseStatus(UseStatus useStatus) {
		if (useStatusSet == null) {
			useStatusSet = new HashSet<UseStatus>();
		}
		useStatusSet.add(useStatus);
	}

	private void createArticleFromFeedItem(FeedItem feedItem, Set<Tag> tags,
			Article article) {
		article.setTitle(feedItem.getTitle());
		article.setContent(feedItem.getContent());
		article.setSource(feedItem.getSource());
		article.setAuthor(feedItem.getAuthor());
		article.setFans(feedItem.getFans());
		article.addSavedFans(this);
		article.setPublishDate(feedItem.getPublishDate());
		// set the fans who first save it
		article.setRecomFans(this);
		article.setSubmitDate(new Date());
		article.addTags(tags);
		article.setUrl(feedItem.getUrl());
		article.setPersistence(this.getPersistence());
		article.save();
		for (Tag tag : tags) {
			tag.addArticle(article);
		}

		feedItem.setArticle(article);

	}

	void editArticle(Article article, Tag tag) {
		article.setPersistence(this.getPersistence());
		article.save();
		// this.addFansTag(tag);
		this.addHot(EDIT_ARTICLE_SCORE);
	}

	void editRootTag(RootTag tag) {
		tag.setLastModifyFans(this);
		tag.setLastModifyDate(new Date());
		tag.setPersistence(this.getPersistence());
		tag.save();
		this.addHot(EDIT_ROOTTAG_SCORE);
		addFansTag(tag);
	}

	@Override
	/**
	 * id相等认为是同一对象
	 */
	public boolean equals(Object obj) {
		return obj == null ? false : this.fansId == ((Fans) obj).getFansId();
	}

	public Set<Article> getArticleSet() {
		return articleSet;
	}

	/**
	 * @return Returns the blog.
	 * @uml.property name="blog"
	 */
	public String getBlog() {
		return blog;
	}

	public String getCity() {
		return city;
	}

	/**
	 * @return Returns the descn.
	 * @uml.property name="descn"
	 */
	public String getDescn() {
		return descn;
	}

	/**
	 * @return Returns the email.
	 * @uml.property name="email"
	 */
	public String getEmail() {
		return email;
	}

	public int getEmailOpenType() {
		return emailOpenType;
	}

	/**
	 * @return Returns the fansId.
	 * @uml.property name="fansId"
	 */
	public int getFansId() {
		return fansId;
	}

	public Set<Feed> getFeeds() {
		return feeds;
	}

	public Set getGroups() {
		return groups;
	}

	public int getHot() {
		return hot;
	}

	/**
	 * @return Returns the icon.
	 * @uml.property name="icon"
	 */
	public String getIcon() {
		return icon;
	}

	public Date getJoinDate() {
		return joinDate;
	}

	public String getName() {
		return name;
	}

	/**
	 * @return Returns the nickName.
	 * @uml.property name="nickName"
	 */
	public String getNickName() {
		return nickName;
	}

	public Set<RootTag> getRootTagSet() {
		return rootTagSet;
	}

	public int getStatus() {
		return status;
	}

	public Set<FansSubFeed> getSubFeedSet() {
		return subFeedSet;
	}

	public Set<FansUsedTag> getUsedTagSet() {
		return usedTagSet;
	}

	public Set<UseStatus> getUseStatusSet() {
		return useStatusSet;
	}

	@Override
	/**
	 * 简单的覆写了hashCode方法，给hashSet的contains方法使用
	 */
	public int hashCode() {
		return this.fansId * 31 + 7;
	}

	/**
	 * 推荐一个feedItem，将生成文章
	 * 
	 * @param feedItem
	 * @param tag
	 */
	void saveFeedItem(FeedItem feedItem, Set<Tag> tags, Article article) {
		if (article.getArticleId() <= 0) {// 没被收藏过
			createArticleFromFeedItem(feedItem, tags, article);
		} else {
			saveArticle(tags, article);
		}

		Fans fans = feedItem.getFans();
		fans.setPersistence(this.getPersistence());
		// for (Tag tag : tags) {
		// this.addFansTag(tag);
		// // 发表该日志的fans也可以获得tag
		// fans.addFansTag(tag);
		// }
		// 收藏人获得相应积分
		this.addHot(SAVE_ARTICLE_SCORE);
	}

	void removeGroup(Group group) {
		groups.remove(group);
		group.removeFans(this);
		group.increaseFansCount(-1);
	}

	public void setArticleSet(Set<Article> articleSet) {
		this.articleSet = articleSet;
	}

	/**
	 * @param blog
	 *            The blog to set.
	 * @uml.property name="blog"
	 */
	public void setBlog(String blog) {
		this.blog = blog;
	}

	public void setCity(String city) {
		this.city = city;
	}

	/**
	 * @param descn
	 *            The descn to set.
	 * @uml.property name="descn"
	 */
	public void setDescn(String descn) {
		this.descn = descn;
	}

	/**
	 * @param email
	 *            The email to set.
	 * @uml.property name="email"
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	public void setEmailOpenType(int emailOpenType) {
		this.emailOpenType = emailOpenType;
	}

	/**
	 * @param fansId
	 *            The fansId to set.
	 * @uml.property name="fansId"
	 */
	public void setFansId(int fansId) {
		this.fansId = fansId;
	}

	public void setFeeds(Set<Feed> feeds) {
		this.feeds = feeds;
	}

	public void setGroups(Set<Group> groups) {
		this.groups = groups;
	}

	public void setHot(int hot) {
		this.hot = hot;
	}

	/**
	 * @param icon
	 *            The icon to set.
	 * @uml.property name="icon"
	 */
	public void setIcon(String icon) {
		this.icon = icon;
	}

	public void setJoinDate(Date joinDate) {
		this.joinDate = joinDate;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @param nickName
	 *            The nickName to set.
	 * @uml.property name="nickName"
	 */
	public void setNickName(String nickName) {
		this.nickName = nickName;
	}

	public void setRootTagSet(Set<RootTag> rootTagSet) {
		this.rootTagSet = rootTagSet;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	public void setSubFeedSet(Set<FansSubFeed> subFeedSet) {
		this.subFeedSet = subFeedSet;
	}

	public void setUsedTagSet(Set<FansUsedTag> usedTagSet) {
		this.usedTagSet = usedTagSet;
	}

	public void setUseStatusSet(Set<UseStatus> useStatusSet) {
		this.useStatusSet = useStatusSet;
	}

	/**
	 * 用户对一个roottag的使用反馈
	 * 
	 * @param status
	 * @param tag
	 */
	void judgeRootTag(int status, Tag tag) {
		this.addFansTag(tag);
		this.addHot(JUDGE_ROOTTAG_SCORE);
		UseStatus oldStatus = null;

		Set<UseStatus> statusSet = ((RootTag) tag).getUseStatusSet();
		for (UseStatus us : statusSet) {
			if (us.getFans().getFansId() == this.getFansId()) {
				oldStatus = us;
				break;
			}
		}

		if (null == oldStatus) {
			oldStatus = new UseStatus();
			oldStatus.setFans(this);
			oldStatus.setTag(tag);
		}

		oldStatus.setStatus(status);
		oldStatus.setSubmitDate(new Date());

		this.getPersistence().save(oldStatus);
	}

	/**
	 * 用户订阅feed<br>
	 * Author:pesome<br>
	 * Date:2007-1-22<br>
	 * 
	 * @param feed
	 */
	void subFeed(Feed feed) {
		for (FansSubFeed fsf : subFeedSet) {
			if (feed.getFeedId() == fsf.getFeed().getFeedId()) {
				return;
			}
		}

		feed.increaseSubscribeCount(1);
		feed.setPersistence(this.getPersistence());
		feed.save();

		FansSubFeed fsf = new FansSubFeed();
		fsf.setFans(this);
		fsf.setSubDate(new Date());
		fsf.setFeed(feed);
		fsf.setPersistence(this.getPersistence());
		fsf.save();

		if (subFeedSet == null) {
			subFeedSet = new HashSet<FansSubFeed>();
		}
		subFeedSet.add(fsf);

	}

	/**
	 * 用户取消订阅feed<br>
	 * Author:pesome<br>
	 * Date:2007-1-22<br>
	 * 
	 * @param feed
	 */
	void unsubFeed(Feed feed) {
		feed.increaseSubscribeCount(-1);

		for (FansSubFeed fsf : subFeedSet) {
			if (feed.getFeedId() == fsf.getFeed().getFeedId()) {
				// subFeedSet.remove(fsf);
				fsf.setPersistence(this.getPersistence());
				fsf.remove();
			}
		}
	}

	public void publishArticle(Article article) {
		article.addSavedFans(this);

	}

	public void unPublishArticle(Article article) {
		article.removeSavedFans(this);

	}

	public void saveArticle(Set<Tag> tags, Article article) {
		article.addTags(tags);
		article.addSavedFans(this);
		article.setPersistence(this.getPersistence());
		article.save();
		this.addHot(SAVE_ARTICLE_SCORE);
	}

	public Set<RootTagDigg> getRootTagDiggSet() {
		return rootTagDiggSet;
	}

	public void setRootTagDiggSet(Set<RootTagDigg> rootTagDiggSet) {
		this.rootTagDiggSet = rootTagDiggSet;
	}

	public void diggRootTag(RootTag tag) {
		RootTagDigg digg = new RootTagDigg();
		digg.setFans(this);
		digg.setDiggDate(new Date());
		digg.setTag(tag);
		this.getPersistence().save(digg);
		tag.addDigg(digg);
		this.getPersistence().save(tag);
		if (rootTagDiggSet == null) {
			rootTagDiggSet = new HashSet<RootTagDigg>();
		}
		rootTagDiggSet.add(digg);
		this.addHot(DIGG_SCORE);
		this.addFansTag(tag);
	}
}
